#pragma once
#include "CBitmapSource.h"
#include "REQUEST.h"


class ImageCache;

class CBitmapImage :
	public CBitmapSource
{

	enum BitmapImageState
	{
		Initial = 0x0,
		Downloading = 0x1,
		Decoding = 0x2,
		Failed = 0x3,
		Decoded = 0x4,
		HasEncodedImageOnly = 0x5
	};

public: 
	static HRESULT Create(CDependencyObject * * ppObject, CREATEPARAMETERS * pCreate);
	virtual XUINT32 GetTypeIndex() const;
	virtual HRESULT SetValue(CDependencyProperty * pdp, CValue * pValue);
	virtual HRESULT GetValue(CDependencyProperty * pdp, CValue * pValue);
	virtual XBOOL ParticipatesInManagedTreeInternal();
	virtual HRESULT OnManagedPeerCreated(XBOOL fIsCustomDOType, XBOOL fIsManagedPeerTaken);
	virtual XINT32 IsFiringEvents();
	virtual HRESULT AddEventListener(CDependencyProperty * pdp, CValue * pValue, XINT32 iListenerType, CValue * pResult, XINT32 fHandledEventsToo);
	virtual HRESULT RemoveEventListener(CDependencyProperty * pdp, CValue * pValue);
	virtual HRESULT AddCallback(CBitmapImageReportCallback * pImageErrorCallback);
	virtual void RemoveCallback(CBitmapImageReportCallback * pImageErrorCallback);
	virtual HRESULT ReloadImage();
	virtual HRESULT ReloadReleasedSoftwareImage();
	virtual HRESULT HasProtectedContent(XBOOL * pHasProtectedContent);
	virtual HRESULT GetSoftwareSurfaceForPrinting(struct IPALSurface * * ppSoftwareSurface);
	virtual HRESULT GetCacheIdentifier(CXString * * ppCacheIdentifier);
	virtual HRESULT CancelDownload();
	virtual HRESULT CreationComplete();
	HRESULT TryUseCachedHardwareResources(SurfaceCache * pSurfaceCache);
	XFLOAT m_downloadProgress;
	enum Xcp_BitmapCreateOptions m_nCreateOptions;
	XINT32 m_decodePixelWidth;
	XINT32 m_decodePixelHeight;
	XBOOL m_fReloadNeeded:1;

protected: 
	CBitmapImage(CCoreServices * pCore);
	virtual ~CBitmapImage();
	virtual HRESULT EnterImpl(CDependencyObject * pNamescopeOwner, struct EnterParams params);
	virtual HRESULT LeaveImpl(CDependencyObject * pNamescopeOwner, struct LeaveParams params);
	virtual HRESULT RevokeImpl(CDependencyProperty * pdp, CDependencyObject * pNamescopeOwner);
	virtual HRESULT OnSourceSet();
	HRESULT OnImageDownloadProgress(XFLOAT downloadProgress);
	virtual HRESULT OnDownloadImageAvailable(struct IImageAvailableResponse * pResponse);
	HRESULT FireImageFailed(XUINT32 iErrorCode);
	virtual XUINT32 GetDecodeWidth();
	virtual XUINT32 GetDecodeHeight();
	void ResetCacheIdentifier();
	HRESULT FireImageDownloadEvent();
	HRESULT FireImageOpened();
	virtual HRESULT ResetCallbackEvents();
	virtual HRESULT MarkHandledCallbackEvents();
	virtual HRESULT ResetForSourceChange(XBOOL mustKeepSoftwareSurface);
	HRESULT TriggerReloadImage(XBOOL checkForParsing);
	virtual HRESULT HandleLostResources(SurfaceCache * pSurfaceCache, XBOOL * pWasDeviceLost);
private: 
	HRESULT RedecodeEncodedImage();
	void SetBitmapState(enum CBitmapImage::BitmapImageState newState);
	XBOOL ShouldFirePublicBitmapImageEvents();
	HRESULT UpdateAbsoluteUri(CXString * pSource);
	HRESULT UseImageCache(ImageCache * pImageCache);
	CXcpList<REQUEST> * m_pEventList;
	xvector<xref_ptr<CBitmapImageReportCallback> > m_imageReportCallbacks;
	xvector<xref_ptr<CBitmapImageReportCallback> > m_imageReportAlreadyReportedCallbacks;
	ImageCache * m_pImageCache;
	CXString * m_pCacheIdentifier;
	enum CBitmapImage::BitmapImageState m_bitmapState;
	struct IPALImageSource * m_pEncodedImage;
	struct IPALUri * m_pAbsoluteUri;
};